home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that the name of Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
- * POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
- //
- // Sample SceneViewer program.
- // This program reads in a Inventor datafile, and creates a SceneViewer
- // to allow interaction with it.
- //
-
- #include <X11/Intrinsic.h>
- #include <X11/keysym.h>
-
- #include <Inventor/SoBaseKit.h>
- #include <Inventor/SoDB.h>
- #include <Inventor/SoInteraction.h>
- #include <Inventor/SoNodeKit.h>
- #include <Inventor/SoSelection.h>
- #include <Inventor/SoXt.h>
- #include <Inventor/SoSensor.h>
- #include <Inventor/SbTime.h>
-
- #include "SoSceneViewer.h"
- #include "Common.h"
- #include <limits.h>
- #include <sys/types.h>
- #include <sys/prctl.h>
- #include <sys/schedctl.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <stdlib.h>
- #include <getopt.h>
- #include <string.h>
- #include <stdio.h>
- #include <time.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <net/if.h>
- #include <sys/ioctl.h>
- #include <net/soioctl.h>
- #include <arpa/inet.h>
- #include "multicast.h"
-
- //
- // The following is used by printScreen
- //
- extern "C" {
- struct IMAGE;
- #define IMAGIC 0732
-
- /* colormap of images */
- #define CM_NORMAL 0 /* file contains rows of values which
- * are either RGB values (zsize == 3)
- * or greyramp values (zsize == 1) */
- #define CM_DITHERED 1
- #define CM_SCREEN 2 /* file contains data which is a screen
- * image; getrow returns buffer which
- * can be displayed directly with
- * writepixels */
- #define CM_COLORMAP 3 /* a colormap file */
-
- #define TYPEMASK 0xff00
- #define BPPMASK 0x00ff
- #define ITYPE_VERBATIM 0x0000
- #define ITYPE_RLE 0x0100
- #define ISRLE(type) (((type) & 0xff00) == ITYPE_RLE)
- #define ISVERBATIM(type) (((type) & 0xff00) == ITYPE_VERBATIM)
- #define BPP(type) ((type) & BPPMASK)
- #define RLE(bpp) (ITYPE_RLE | (bpp))
- #define VERBATIM(bpp) (ITYPE_VERBATIM | (bpp))
- #define IBUFSIZE(pixels) ((pixels+(pixels>>6))<<2)
- #define RLE_NOP 0x00
-
- #define ierror(p) (((p)->flags&_IOERR)!=0)
- #define ifileno(p) ((p)->file)
- #define getpix(p) (--(p)->cnt>=0 ? *(p)->ptr++ : ifilbuf(p))
- #define putpix(p,x) (--(p)->cnt>=0 \
- ? ((int)(*(p)->ptr++=(unsigned)(x))) \
- : iflsbuf(p,(unsigned)(x)))
-
-
- extern IMAGE *iopen( char *, char *, unsigned int, unsigned int, unsigned int, unsigned, unsigned int );
- extern int iclose( IMAGE * );
- extern int putrow( IMAGE *, unsigned short *, unsigned int, unsigned int );
- extern int cpacktorgb( unsigned long *, unsigned short *, unsigned short *, unsigned short *, int );
- int ioctl(int fildes, int request, ... ) ;
- }
-
-
-
-
- extern int timerflag;
- extern void myreadcallback(void *, SoSensor *);
- extern void mywritecallback(void *, SoSensor *);
- SoSceneViewer *mysv;
- SoDataSensor *envirosensor;
- SoTimerSensor *timersensor;
- extern SoWriteAction nwa;
- struct sockaddr_in inaddr,outaddr;
- int inaddrlen,outaddrlen, infd, outfd, cnt, i;
- struct ip_mreq mreq;
- char *group = EXAMPLE_GROUP;
- u_short port = EXAMPLE_PORT;
- u_char ttl = EXAMPLE_TTL;
- int send_mode = 1;
- int iflag = 0;
- char *interface;
- struct in_addr ifaddr;
- struct in_addr grpaddr;
-
-
-
-
-
- void
- printScreen( SoSceneViewer *sv)
- {
- unsigned long *rgbArray;
- short numRows, numColumns;
- IMAGE *oimage;
- int writeerr, y;
- unsigned long *ss;
- unsigned short *rs, *gs, *bs;
-
- //
- // Grabs screen and saves in an .rgb file
- // (this code was stolen from 4Dgifts/scrsave.c.)
- //
- printf("Grabbing screen...");
- rgbArray = sv->copyScreen( numRows, numColumns );
-
- // open the image file
- oimage = iopen( "/usr/tmp/inventor.rgb", "w", RLE(1), 3,
- numColumns, numRows, 3 );
- writeerr = 0;
-
- // malloc buffers
- rs = (unsigned short *)malloc(numColumns*sizeof(short));
- gs = (unsigned short *)malloc(numColumns*sizeof(short));
- bs = (unsigned short *)malloc(numColumns*sizeof(short));
-
- // write the data to the image file
- ss = rgbArray;
- for( y = 0; y < numRows; y++ ) {
- cpacktorgb( ss, rs, gs, bs, numColumns );
- if( putrow( oimage, rs, y ,0 ) != numColumns)
- writeerr = 1;
- if( putrow( oimage, gs, y, 1 ) != numColumns)
- writeerr = 1;
- if( putrow( oimage, bs, y, 2 ) != numColumns)
- writeerr = 1;
- ss += numColumns;
- }
-
- // free buffers
- free(rs);
- free(gs);
- free(bs);
-
- // close the image file
- if( iclose( oimage ) < 0 )
- writeerr = 1;
-
- // exit with a bad status on write error
- if (writeerr == 1) {
- fprintf( stderr, "ERROR: image file write error!\n" );
- exit(1);
- }
- printf("...done. (see /usr/tmp/inventor.rgb)\n");
- ////////////////////////////////////////////////////////////
- // end of scrsave.c stolen code
- ////////////////////////////////////////////////////////////
- }
-
- static SbBool
- getArgs(int argc, char **argv, char *&envFile, char *&filename)
- {
- SbBool ok = TRUE;
-
- envFile = NULL;
- filename = NULL;
-
- if (argc == 2) {
- filename = argv[1];
- }
- else if (argc > 2) {
- // see if there is a -e before the file name
- if (strcmp(argv[1], "-p") == 0) {
- port = (u_short)atoi(argv[2]);
- if (argc > 3)
- filename = argv[3];
- }
- else if (argc == 4) {
- // maybe the -e is after the file name
- if (strcmp(argv[2], "-p") == 0) {
- port = (u_short)atoi(argv[3]);
- filename = argv[1];
- }
- }
- else ok = FALSE;
- }
- return ok;
- }
-
- void
- SoXtFullViewer::viewingToggleCB(void *v, SbBool flag)
- {
- ((SoXtFullViewer *)v)->setViewing(flag);
- if(! mysv->isViewing())
- {
- #ifdef MYDEBUG
- printf("TIMER OFF, from pick menu\n");
- #endif
- timersensor->unschedule();
- timerflag=0;
- }
- else
- {
- #ifdef MYDEBUG
- printf("TIMER ON, from pick menu\n");
- #endif
- timersensor->schedule(SbTime((unsigned long)DATATIME));
- timerflag=1;
-
- }
-
- }
-
-
-
- void main(int argc, char **argv)
- {
- Widget mainWindow;
- SoSceneViewer *sv;
- SoInput in;
- char *envFile, *filename;
-
- // check usage
- if (! getArgs(argc, argv, envFile, filename )) {
- fprintf(stderr, "usage: SharedSV [-p port_number] [file.iv]\n");
- exit( 1 );
- }
-
-
-
- // init Inventor
- mainWindow = SoXt::init(argv[0]);
-
- // init commsstuff
- infd=openMulticastSocket(&inaddr,1,0,EXAMPLE_GROUP,NULL,"r");
- outfd=openMulticastSocket(&outaddr,1,0,EXAMPLE_GROUP,NULL,"w");
- // Turn on non-blocking I/O
- if( fcntl( infd, F_SETFL, FNDELAY ) < 0 ) {
- perror( "fcntl F_SETFL, FNDELAY" ) ;
- }
-
-
- #ifdef MYDEBUG
- printf("infd=%d, outfd=%d\n",infd,outfd);
- #endif
-
- outaddrlen=sizeof(outaddr);
- inaddrlen=sizeof(inaddr);
-
-
-
- // read the file in, creating a selection node as the root
- // of the scene graph.
- SoSelection *selRoot = new SoSelection;
- selRoot->ref();
- if (filename != NULL && in.openFile(filename) ) {
-
- fprintf( stderr, "Reading input file...");
- SoNode *n;
- while ((SoDB::read(&in, n) != FALSE) && (n != NULL))
- selRoot->addChild(n);
-
- if ( selRoot->getNumChildren() == 0 )
- fprintf(stderr, "No data read; creating empty scene.\n" );
- else
- fprintf(stderr, "done.\n");
- }
-
- //
- // Create the SceneViewer
- //
- mysv = sv = new SoSceneViewer(selRoot, envFile);
- selRoot->unref();
-
- // The typeIds in this list specify which node types (and subclasses
- // of those types) are candidates for selection. In this case,
- // we want node kits to be selected (SoBaseKit and its subclasses).
- SoTypeList *priorities = selRoot->getSelectTypePriorityList();
- if ( priorities )
- priorities->insert( SoBaseKit::getClassTypeId(), 0 );
- //
- // added by smf
- #ifdef MYDEBUG
- printf("TIMER ON\n");
- #endif
- timersensor = new SoTimerSensor(myreadcallback,(void *) NULL);
- timersensor->schedule(SbTime((unsigned long)DATATIME));
-
- //
- // Build and show the SceneViewer
- //
- sv->build(mainWindow);
- sv->show();
- XtRealizeWidget(mainWindow);
-
- // add an event handler for the print screen key test
- // Widget w = sv->getWidget();
- // XtAddEventHandler(w, KeyPressMask, False,
- //// (XtEventHandler) printScreen,
- // (XtPointer) sv);
-
- // added by smf
-
- #ifdef MYDEBUG
- printf("ENVIRO ON\n");
- #endif
- envirosensor = new SoDataSensor(mywritecallback,(void *)NULL);
- envirosensor->attach(mysv->lightsCameraEnvironment);
- //
- // Loop forever
- //
- SoXt::mainLoop();
- }
-
-
-
-
- /* BEGIN PROTOTYPES -S multicast.c */
- static int checkInterface( const char *interface, int fd, char mode,
- struct in_addr *ifaddr ) ;
- /* END PROTOTYPES -S multicast.c */
-
-
- int openMulticastSocket(
- struct sockaddr_in *addr,
- // u_short port,
- u_char ttl,
- u_char loop,
- const char *group,
- const char *interface,
- const char *mode_str
- )
- {
- int fd ;
- int st ;
- int on;
- char mode = tolower( *mode_str ) ;
- struct in_addr ifaddr;
- struct in_addr grpaddr;
- struct ip_mreq mreq;
-
- grpaddr.s_addr = inet_addr( group ) ;
- if( !IN_MULTICAST( grpaddr.s_addr ) ) {
- fprintf( stderr, "Invalid multicast group address: %s\n", group ) ;
- return( -1 ) ;
- }
-
- if( strlen( mode_str ) != 1 || ( mode != 'r' && mode != 'w' ) ) {
- fprintf( stderr, "openMulticastSocket: improper mode `%s'\n",
- mode_str ) ;
- return( -1 ) ;
- }
-
- fd = socket( AF_INET, SOCK_DGRAM, 0 ) ;
- if( fd < 0 ) {
- perror( "socket" ) ;
- return( fd ) ;
- }
-
- bzero( addr, sizeof( *addr ) ) ;
- addr->sin_family = AF_INET ;
- addr->sin_addr.s_addr = INADDR_ANY ;
- addr->sin_port = htons( port ) ;
-
- ifaddr.s_addr = INADDR_ANY;
-
- if( interface != NULL ) {
- if( ( st = checkInterface( interface, fd, mode, &ifaddr ) ) < 0 ) {
- close( fd ) ;
- return( st ) ;
- }
- }
-
- switch( mode ) {
-
- case 'w' :
- if( setsockopt( fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
- sizeof(ttl) ) ) {
- close( fd ) ;
- perror( "setsockopt TTL" ) ;
- return( -1 ) ;
- }
-
- if( setsockopt( fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop,
- sizeof(loop) )) {
- close( fd ) ;
- perror( "setsockopt LOOP" ) ;
- return( -1 ) ;
- }
-
- addr->sin_addr = grpaddr;
- break ;
-
- case 'r' :
- /*
- * Allow multiple instances of this program to listen on the same
- * port on the same host. By default only 1 program can bind
- * to the port on a host.
- */
- on = 1;
- // if( setsockopt( fd, SOL_SOCKET, SO_REUSEPORT, &on,
- if( setsockopt( fd, SOL_SOCKET, SO_REUSEPORT, &on,
- sizeof(on) ) < 0 ) {
- close( fd ) ;
- perror( "setsockopt REUSEPORT" ) ;
- return( -1 ) ;
- }
-
- if( bind( fd, addr, sizeof(*addr) ) < 0 ) {
- close( fd ) ;
- perror( "bind" ) ;
- return( -1 ) ;
- }
-
- mreq.imr_multiaddr = grpaddr;
- mreq.imr_interface = ifaddr;
- if( setsockopt( fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
- &mreq, sizeof(mreq) ) < 0 ) {
- close( fd ) ;
- perror( "setsockopt ADD" ) ;
- return( -1 ) ;
- }
- break ;
-
- }
-
- return( fd ) ;
- }
-
-
-
- /*
- * Make sure the specified interface exists and is capable of doing
- * multicasting.
- */
- static int checkInterface(
- const char *interface,
- int fd,
- char mode,
- struct in_addr *ifaddr
- )
- {
- int i ;
- struct ifconf ifc ;
- struct ifreq *ifr ;
- char buf[BUFSIZ] ;
-
- ifc.ifc_len = sizeof( buf ) ;
- ifc.ifc_buf = buf ;
- if( ioctl( fd, SIOCGIFCONF, (char *) &ifc ) < 0 ) {
- perror( "ioctl SIOCGIFCONF" ) ;
- return( -1 ) ;
- }
-
- ifr = ifc.ifc_req;
- for( i = ifc.ifc_len/sizeof(*ifr) ; --i >= 0 ; ifr++ ) {
- if( ifr->ifr_addr.sa_family != AF_INET )
- continue ;
-
- if( strncmp( ifr->ifr_name, interface, strlen( ifr->ifr_name ) )
- == 0 ) {
- /* Obtain the interface's assigned network address */
- *ifaddr = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr ;
-
- if( ioctl( fd, SIOCGIFFLAGS, (char *) ifr ) < 0 ) {
- perror( "ioctl SIOCGIFFLAGS" ) ;
- return( -1 ) ;
- }
- if( !( ifr->ifr_flags & IFF_MULTICAST ) ) {
- fprintf( stderr, "%s: interface doesn't support multicasting\n",
- interface ) ;
- return( -1 ) ;
- }
-
- /* Specify the interface to use when sending packets */
- if( mode == 'w' && setsockopt( fd, IPPROTO_IP, IP_MULTICAST_IF,
- ifaddr, sizeof(*ifaddr) ) < 0 ) {
- perror( "setsockopt MULTICAST" ) ;
- return( -1 ) ;
- }
- break;
- }
- }
-
- if( ifaddr->s_addr == INADDR_ANY ) {
- fprintf(stderr, "%s: invalid or unknown interface\n", interface);
- return( -1 ) ;
- }
-
- return( 0 ) ;
- }
-